package com.chuangke.common.report;

import java.io.InputStream;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;

import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.JasperRunManager;
import net.sf.jasperreports.engine.export.HtmlExporter;
import net.sf.jasperreports.engine.export.JRPdfExporter;
import net.sf.jasperreports.engine.export.JRXlsExporter;
import net.sf.jasperreports.engine.export.ooxml.JRDocxExporter;
import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.export.SimpleExporterInput;
import net.sf.jasperreports.export.SimpleHtmlExporterOutput;
import net.sf.jasperreports.export.SimpleHtmlReportConfiguration;
import net.sf.jasperreports.export.SimpleOutputStreamExporterOutput;
import net.sf.jasperreports.export.SimpleXlsReportConfiguration;
import net.sf.jasperreports.j2ee.servlets.ImageServlet;
import net.sf.jasperreports.web.util.WebHtmlResourceHandler;

public class JasperReportUtils {

    public static final Logger logger = LoggerFactory.getLogger(JasperReportUtils.class);

    public static final String HTML_TYPE = "html";
    public static final String PDF_TYPE = "pdf";
    public static final String EXCEL_TYPE = "xls";
    public static final String WORD_TYPE = "word";

    public static void export(HttpServletRequest request, HttpServletResponse response, String type, String reportName,
                              String filename, JasperReportData jasperReportData) throws Exception {
        JasperPrint jasperPrint = getJasperPrint(reportName, jasperReportData);

        if ("pdf".equals(type)) {
            String fileName = new String((filename + ".pdf").getBytes("GBK"), "ISO8859_1");
            response.setContentType("application/pdf");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.setCharacterEncoding("UTF-8");

            JRPdfExporter exporter = new JRPdfExporter();
            exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
            exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(response.getOutputStream()));
            exporter.exportReport();
        } else if ("xls".equals(type)) {
            String fileName = new String((filename + ".xls").getBytes("GBK"), "ISO8859_1");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.setContentType("application/vnd_ms-excel");

            JRXlsExporter exporter = new JRXlsExporter();
            exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
            exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(response.getOutputStream()));
            SimpleXlsReportConfiguration configuration = new SimpleXlsReportConfiguration();
            configuration.setOnePagePerSheet(true);
            exporter.setConfiguration(configuration);
            exporter.exportReport();
        } else if ("html".equals(type)) {
            request.getSession().setAttribute(ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE, jasperPrint);
            response.setContentType("text/html;charset=utf-8");

            HtmlExporter exporterHTML = new HtmlExporter();
            exporterHTML.setExporterInput(new SimpleExporterInput(jasperPrint));

            SimpleHtmlExporterOutput exporterOutput = new SimpleHtmlExporterOutput(response.getOutputStream());
            exporterOutput.setImageHandler(new WebHtmlResourceHandler("image?image={0}"));
            exporterHTML.setExporterOutput(exporterOutput);

            SimpleHtmlReportConfiguration reportExportConfiguration = new SimpleHtmlReportConfiguration();
            reportExportConfiguration.setWhitePageBackground(false);
            reportExportConfiguration.setRemoveEmptySpaceBetweenRows(true);
            exporterHTML.setConfiguration(reportExportConfiguration);
            exporterHTML.exportReport();
        } else if ("docx".equals(type)) {
            String fileName = new String((filename + ".docx").getBytes("GBK"), "ISO8859_1");
            response.setContentType("application/msword;charset=utf-8");
            response.setHeader("Content-disposition", "attachment; filename=" + fileName);

            JRDocxExporter exporter = new JRDocxExporter();
            exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
            exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(response.getOutputStream()));
            exporter.exportReport();
        }
    }

    public static void print(HttpServletRequest request, HttpServletResponse response, String reportName,
                             JasperReportData jasperReportData) throws Exception {
        ClassPathResource resource = new ClassPathResource("jasperreport/" + reportName + ".jasper");
        InputStream jasperStream = resource.getInputStream();

        response.setContentType("application/pdf");
        response.setHeader("Content-Disposition", "inline;");

        JasperRunManager.runReportToPdfStream(jasperStream, response.getOutputStream(),
                jasperReportData.getParameters(), jasperReportData.getDetailDataSource());
    }

    public static void printBatch(HttpServletRequest request, HttpServletResponse response,
                                  List<JasperPrint> jasperPrintList) throws Exception {
        response.setContentType("application/pdf");
        response.setHeader("Content-Disposition", "inline;");
        response.setCharacterEncoding("UTF-8");

        JRPdfExporter exporter = new JRPdfExporter();
        exporter.setExporterInput(SimpleExporterInput.getInstance(jasperPrintList));
        exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(response.getOutputStream()));
        exporter.exportReport();
    }

    public static JasperPrint getJasperPrint(String reportName, JasperReportData jasperReportData) throws Exception {
        ClassPathResource resource = new ClassPathResource("jasperreport/" + reportName + ".jasper");
        InputStream jasperStream = resource.getInputStream();
        JasperReport jasperReport = (JasperReport) JRLoader.loadObject(jasperStream);
        return JasperFillManager.fillReport(jasperReport, jasperReportData.getParameters(),
                jasperReportData.getDetailDataSource());
    }

}
